﻿Imports Microsoft.WindowsAPICodePack.Dialogs

''' <summary>
''' TaskDialog Wrapper.
''' By implementing DisposableBaseClass, you are announcing instances
''' of the MRUTaskDialog type allocate resources that need to be disposed.
''' </summary>
Friend Class MRUTaskDialog
    Inherits DisposableBaseClass

#Region "Member Variables"

    Private m_bDisposed As Boolean
    Private ReadOnly m_oTaskDialog As TaskDialog

#End Region

#Region "Constructors"

    ''' <summary>
    ''' Initializes a new instance of the <see cref="TaskDialog"/> class.
    ''' </summary>
    Public Sub New()
        Me.New(Nothing, False)
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="TaskDialog"/> class.
    ''' </summary>
    ''' <param name="oParentForm">parent form</param>
    ''' <param name="bModal">if set to <c>true</c> [modal].</param>
    Public Sub New(oParentForm As Form, bModal As Boolean)
        Try
            m_oTaskDialog = New TaskDialog()

            If bModal Then
                If Form.ActiveForm IsNot Nothing Then
                    m_oTaskDialog.OwnerWindowHandle = oParentForm.Handle
                End If
            End If
        Catch oExp As Exception
            ' If we have an exception in the constructor, 
            ' we need to dispose of resources allocated before the exception occured. 
            LogException(oExp)
            Dispose()
            Throw
        End Try
    End Sub

#End Region

#Region "Dispose(bool bDisposing)"

    ''' <summary>
    ''' Releases unmanaged and - optionally - managed resources. This method executes in two distinct 
    ''' scenarios. If disposing equals true, the method has been called directly or indirectly by a 
    ''' user's code. Managed and unmanaged resources can be disposed. If disposing equals false, the 
    ''' method has been called by the runtime from inside the finalizer and you should not reference 
    ''' other objects because of the nondeterministic nature of finalization in c#. 
    ''' </summary>
    ''' <param name="bDisposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
    Protected Overrides Sub Dispose(bDisposing As Boolean)
        Try
            If Not m_bDisposed Then
                ' If disposing equals true, dispose all managed and unmanaged resources.
                If bDisposing Then
                    ' Dispose managed resources, e.g.:
                    ' Be sure to use an empty try-catch or SafeDispose for each resource 
                    ' so an exception on one doesn't stop other resouces from being disposed.
                    SafeDispose(m_oTaskDialog)

                    ' Clean up unmanaged objects. If disposing is false, only the following code is executed. e.g.:
                    ' free up m_oUnmanagedResource

                End If
            End If
            m_bDisposed = True

            ' Call parent class's Dispose(bool) to dispose of its resources
            MyBase.Dispose(m_bDisposed)
        Catch
        End Try
    End Sub

#End Region

#Region "Properties"

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Controls As DialogControlCollection(Of TaskDialogControl)
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.Controls
        End Get
    End Property

    ''' <summary>
    ''' Gets or sets the text.
    ''' </summary>
    ''' <value>The text.</value>
    Public Property Text() As String
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.Text
        End Get
        Set(value As String)
            CheckIfDisposed()
            m_oTaskDialog.Text = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the instruction text.
    ''' </summary>
    ''' <value>The instruction text.</value>
    Public Property InstructionText() As String
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.InstructionText
        End Get
        Set(value As String)
            CheckIfDisposed()
            m_oTaskDialog.InstructionText = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the icon.
    ''' </summary>
    ''' <value>The icon.</value>
    Public Property Icon() As TaskDialogStandardIcon
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.Icon
        End Get
        Set(value As TaskDialogStandardIcon)
            CheckIfDisposed()
            m_oTaskDialog.Icon = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets a value indicating whether this <see cref="MRUTaskDialog"/> is cancelable.
    ''' </summary>
    ''' <value><c>true</c> if cancelable; otherwise, <c>false</c>.</value>
    Public Property Cancelable() As Boolean
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.Cancelable
        End Get
        Set(value As Boolean)
            CheckIfDisposed()
            m_oTaskDialog.Cancelable = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the caption.
    ''' </summary>
    ''' <value>The caption.</value>
    Public Property Caption() As String
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.Caption
        End Get
        Set(value As String)
            CheckIfDisposed()
            m_oTaskDialog.Caption = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the startup location.
    ''' </summary>
    ''' <value>The startup location.</value>
    Public Property StartupLocation() As TaskDialogStartupLocation
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.StartupLocation
        End Get
        Set(value As TaskDialogStartupLocation)
            CheckIfDisposed()
            m_oTaskDialog.StartupLocation = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets a value indicating whether [details expanded].
    ''' </summary>
    ''' <value><c>true</c> if [details expanded]; otherwise, <c>false</c>.</value>
    Public Property DetailsExpanded() As Boolean
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.DetailsExpanded
        End Get
        Set(value As Boolean)
            CheckIfDisposed()
            m_oTaskDialog.DetailsExpanded = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the details collapsed label.
    ''' </summary>
    ''' <value>The details collapsed label.</value>
    Public Property DetailsCollapsedLabel() As String
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.DetailsCollapsedLabel
        End Get
        Set(value As String)
            CheckIfDisposed()
            m_oTaskDialog.DetailsCollapsedLabel = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the details expanded label.
    ''' </summary>
    ''' <value>The details expanded label.</value>
    Public Property DetailsExpandedLabel() As String
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.DetailsExpandedLabel
        End Get
        Set(value As String)
            CheckIfDisposed()
            m_oTaskDialog.DetailsExpandedLabel = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the details expanded text.
    ''' </summary>
    ''' <value>The details expanded text.</value>
    Public Property DetailsExpandedText() As String
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.DetailsExpandedText
        End Get
        Set(value As String)
            CheckIfDisposed()
            m_oTaskDialog.DetailsExpandedText = value
        End Set
    End Property

#End Region

#Region "CheckIfDisposed()"

    ''' <summary>
    ''' Allow your Dispose method to be called multiple times, but call this 
    ''' method before doing anything else in public methods or properties. 
    ''' It will throw an exception if the class has been disposed. 
    ''' </summary>
    Private Sub CheckIfDisposed()
        If m_bDisposed Then
            Throw New ObjectDisposedException("MRUTaskDialog")
        End If
    End Sub

#End Region

#Region "Methods"

    ''' <summary>
    ''' Shows this instance.
    ''' </summary>
    ''' <returns></returns>
    Public Function Show() As TaskDialogResult
        CheckIfDisposed()
        Return m_oTaskDialog.Show()
    End Function

    ''' <summary>
    ''' Closes this instance.
    ''' </summary>
    Public Sub Close()
        CheckIfDisposed()
        m_oTaskDialog.Close()
    End Sub

    ''' <summary>
    ''' Closes the specified o closing result.
    ''' </summary>
    ''' <param name="oClosingResult">closing result</param>
    Public Sub Close(oClosingResult As TaskDialogResult)
        CheckIfDisposed()
        m_oTaskDialog.Close(oClosingResult)
    End Sub

    ''' <summary>
    ''' Gets or sets the standard buttons.
    ''' </summary>
    ''' <value>The standard buttons.</value>
    Public Property StandardButtons() As TaskDialogStandardButtons
        Get
            CheckIfDisposed()
            Return m_oTaskDialog.StandardButtons
        End Get
        Set(value As TaskDialogStandardButtons)
            CheckIfDisposed()
            m_oTaskDialog.StandardButtons = value
        End Set
    End Property

#End Region

End Class
